/**
 * 导出工具类
 * 提供通用的文件导出和下载功能
 */

/**
 * 导出选项接口
 */
export interface ExportOptions {
  /** 文件名 */
  filename: string
  /** 文件类型 */
  fileType?: 'csv' | 'xlsx' | 'txt'
  /** 是否添加BOM（用于支持中文） */
  addBOM?: boolean
  /** 字符编码 */
  encoding?: string
}

/**
 * 导出工具类
 */
export class ExportUtil {
  /**
   * 下载文本文件
   * @param content 文件内容
   * @param options 导出选项
   */
  static downloadTextFile(content: string, options: ExportOptions): void {
    const {
      filename,
      fileType = 'csv',
      addBOM = true,
      encoding = 'utf-8'
    } = options

    // 添加BOM以支持中文
    const bom = addBOM ? '\uFEFF' : ''
    const finalContent = bom + content

    // 根据文件类型设置MIME类型
    const mimeTypes = {
      csv: 'text/csv;charset=utf-8;',
      xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      txt: 'text/plain;charset=utf-8;'
    }

    const blob = new Blob([finalContent], { type: mimeTypes[fileType] })
    this.downloadBlob(blob, filename)
  }

  /**
   * 下载Blob文件
   * @param blob Blob对象
   * @param filename 文件名
   */
  static downloadBlob(blob: Blob, filename: string): void {
    const url = URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.setAttribute('href', url)
    link.setAttribute('download', filename)
    link.style.visibility = 'hidden'
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    URL.revokeObjectURL(url)
  }

  /**
   * 将数据转换为CSV格式
   * @param data 数据数组
   * @param headers 表头数组
   * @param formatters 字段格式化函数映射
   */
  static convertToCSV<T = any>(
    data: T[],
    headers: string[],
    formatters?: Record<string, (value: any, item: T) => string>
  ): string {
    const csvRows = [headers.join(',')]

    data.forEach(item => {
      const row = headers.map(header => {
        const key = this.getKeyFromHeader(header)
        const value = this.getNestedValue(item, key)
        const formattedValue = formatters?.[key] ? formatters[key](value, item) : value
        return `"${formattedValue || ''}"`
      })
      csvRows.push(row.join(','))
    })

    return csvRows.join('\n')
  }

  /**
   * 从表头获取对应的字段键
   * @param header 表头
   */
  private static getKeyFromHeader(header: string): string {
    // 简单的映射，可以根据实际需要扩展
    const headerMap: Record<string, string> = {
      '告警ID': 'id',
      '设备名称': 'deviceName',
      '告警类型': 'alarmType',
      '告警信息': 'alarmContent',
      '发生时间': 'createTime',
      '用户ID': 'userId',
      '用户名': 'username',
      '角色': 'role',
      '部门': 'department',
      '状态': 'status',
      '创建时间': 'createdAt',
      '更新时间': 'updatedAt'
    }
    return headerMap[header] || header.toLowerCase()
  }

  /**
   * 获取嵌套对象的值
   * @param obj 对象
   * @param path 路径
   */
  private static getNestedValue(obj: any, path: string): any {
    return path.split('.').reduce((current, key) => current?.[key], obj)
  }

  /**
   * 生成带时间戳的文件名
   * @param baseName 基础文件名
   * @param extension 文件扩展名
   */
  static generateFilename(baseName: string, extension: string = 'csv'): string {
    const date = new Date().toISOString().split('T')[0]
    return `${baseName}_${date}.${extension}`
  }

  /**
   * 处理API响应数据并导出
   * @param response API响应
   * @param options 导出选项
   * @param formatters 字段格式化函数映射
   */
  static handleApiResponse<T = any>(
    response: any,
    options: ExportOptions,
    formatters?: Record<string, (value: any, item: T) => string>
  ): void {
    if (!response || !response.data) {
      throw new Error('未获取到数据')
    }

    const { data } = response

    if (typeof data === 'string') {
      // 如果是字符串，直接下载
      this.downloadTextFile(data, options)
    } else if (data instanceof Blob) {
      // 如果是Blob，直接下载
      this.downloadBlob(data, options.filename)
    } else if (Array.isArray(data)) {
      // 如果是数组，转换为CSV
      const headers = options.fileType === 'csv' ? this.getDefaultHeaders() : []
      const csvContent = this.convertToCSV(data, headers, formatters)
      this.downloadTextFile(csvContent, options)
    } else if (data.data && Array.isArray(data.data)) {
      // 如果是分页数据格式
      const headers = options.fileType === 'csv' ? this.getDefaultHeaders() : []
      const csvContent = this.convertToCSV(data.data, headers, formatters)
      this.downloadTextFile(csvContent, options)
    } else {
      throw new Error('不支持的数据格式')
    }
  }

  /**
   * 获取默认表头
   */
  private static getDefaultHeaders(): string[] {
    return ['ID', '名称', '类型', '状态', '创建时间']
  }
}

/**
 * 导出服务类
 * 提供更高级的导出功能
 */
export class ExportService {
  /**
   * 导出告警数据
   * @param data 告警数据
   * @param filename 文件名
   */
  static exportAlarmData(data: any[], filename?: string): void {
    const headers = ['告警ID', '设备名称', '告警类型', '告警信息', '发生时间']
    const formatters = {
      alarmType: (value: any) => {
        // 这里需要导入告警类型转换函数
        return value // 临时返回原值，实际使用时需要导入getAlarmTypeText
      },
      createTime: (value: any) => {
        return value ? new Date(value).toLocaleString() : ''
      }
    }

    const csvContent = ExportUtil.convertToCSV(data, headers, formatters)
    const finalFilename = filename || ExportUtil.generateFilename('告警数据')
    
    ExportUtil.downloadTextFile(csvContent, {
      filename: finalFilename,
      fileType: 'csv'
    })
  }

  /**
   * 导出用户数据
   * @param data 用户数据
   * @param filename 文件名
   */
  static exportUserData(data: any[], filename?: string): void {
    const headers = ['用户ID', '用户名', '姓名', '邮箱', '角色', '部门', '状态', '创建时间']
    const formatters = {
      status: (value: any) => {
        return value ? '启用' : '禁用'
      },
      createdAt: (value: any) => {
        return value ? new Date(value).toLocaleString() : ''
      }
    }

    const csvContent = ExportUtil.convertToCSV(data, headers, formatters)
    const finalFilename = filename || ExportUtil.generateFilename('用户数据')
    
    ExportUtil.downloadTextFile(csvContent, {
      filename: finalFilename,
      fileType: 'csv'
    })
  }

  /**
   * 导出设备数据
   * @param data 设备数据
   * @param filename 文件名
   */
  static exportDeviceData(data: any[], filename?: string): void {
    const headers = ['设备ID', '设备名称', 'IP地址', '端口', '协议', '状态', '位置', '创建时间']
    const formatters = {
      status: (value: any) => {
        return value === 1 ? '在线' : '离线'
      },
      createdAt: (value: any) => {
        return value ? new Date(value).toLocaleString() : ''
      }
    }

    const csvContent = ExportUtil.convertToCSV(data, headers, formatters)
    const finalFilename = filename || ExportUtil.generateFilename('设备数据')
    
    ExportUtil.downloadTextFile(csvContent, {
      filename: finalFilename,
      fileType: 'csv'
    })
  }
}

// 导出默认实例
export default ExportUtil
